﻿using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.ServiceModel;
using ajayumi.develop.win32.Transport.Utils.WinForm;
using ajayumi.develop.win32.Transport.Core;
using ajayumi.develop.win32.Transport.Utils;
using ajayumi.develop.win32.Transport.WCF.Services;

namespace ajayumi.develop.win32.Transport.Client.WinForm.Controls
{
    public partial class UcUpload : UserControl
    {
        #region Variables

        #endregion

        public Action<string> Display { get; set; }

        public UcUpload()
        {
            InitializeComponent();

            ControlHelper.DoubleBuffered(this.dgvUploadFiles, true);
            this.dgvUploadFiles.AutoGenerateColumns = false;
            this.dgvUploadFiles.DataSource = TransTaskManager.Instance.UploadFileCollection;
        }

        private void RaiseDisplay(string text)
        {
            if (this.Display != null)
            { this.Display(text); }
        }

        private void InvokeUploadFile(string rootPath, string[] files)
        {
            ThreadPool.SetMaxThreads(10, 100);
            foreach (string item in files)
            {
                TransportFileServiceClient client = new TransportFileServiceClient();

                string relativePath = Path.GetFileName(item);
                if (string.IsNullOrEmpty(rootPath))
                {
                    rootPath = Path.GetDirectoryName(item);
                }
                else
                {
                    relativePath = item.Replace(rootPath, string.Empty).TrimStart('\\');
                }
                UploadFile uploadFile = new UploadFile(rootPath, relativePath,
                    (file) => { return client.InitUploadFile(file); },
                    (file) => { return client.UploadFile(file); });
                uploadFile.GetBufferSize = () => { return AppConfig.BufferSize; };
                uploadFile.TransReady += (sender, e) =>
                {
                    TransTaskManager.Instance.UploadFileCollection.TransFileReady(e.RelativePath,
                        FileHelper.FormatFileSize(e.FileLength),
                        e.ProgressPercentage);
                };
                uploadFile.TransProgressChanged += (sender, e) =>
                {
                    TransTaskManager.Instance.UploadFileCollection.TransFileProgressChanged(e.RelativePath, e.ProgressPercentage);
                    this.RaiseDisplay(string.Format("{0} {1} 上传进度：{2}%.\r\n", DateTime.Now, e.RelativePath, e.ProgressPercentage));
                };
                uploadFile.TransCompleted += (sender, e) =>
                {
                    TransTaskManager.Instance.UploadFileCollection.TransFileCompleted(e);
                    if (e.Error != null)
                    {
                        this.RaiseDisplay(string.Format("{0} {1} 上传时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, e.RelativePath, e.Error.Message));
                    }
                    else
                    {
                        this.RaiseDisplay(string.Format("{0} {1} 上传完毕.\r\n", DateTime.Now, e.RelativePath));
                    }

                    try
                    {
                        client.Close();
                    }
                    catch (FaultException ex)
                    {
                        client.Abort();
                        this.RaiseDisplay(string.Format("{0} {1} 上传时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, e.RelativePath, ex.Message));
                    }
                    catch (TimeoutException ex)
                    {
                        client.Abort();
                        this.RaiseDisplay(string.Format("{0} {1} 上传时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, e.RelativePath, ex.Message));
                    }
                    catch (Exception ex)
                    {
                        client.Abort();
                        this.RaiseDisplay(string.Format("{0} {1} 上传时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, e.RelativePath, ex.Message));
                    }
                };

                FileInfo fileInfo = new FileInfo(item);
                TransFileItem transFileItem = new TransFileItem()
                {
                    Name = fileInfo.Name,
                    RelativePath = relativePath,
                    FileSize = FileHelper.FormatFileSize(fileInfo.Length),
                    ProgressPercentage = string.Empty
                };
                this.dgvUploadFiles.Invoke(new Action<TransFileItem>(TransTaskManager.Instance.UploadFileCollection.Add),
                    new object[] { transFileItem });

                ThreadPool.QueueUserWorkItem(new WaitCallback(uploadFile.RunWork), item);
            }
        }

        private void tsbtnSelFiles_Click(object sender, EventArgs e)
        {
            if (this.openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.InvokeUploadFile(string.Empty, this.openFileDialog1.FileNames);
            }
        }

        private void tsbtnSelFolder_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dlg = new FolderBrowserDialog())
            {
                if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string rootPath = dlg.SelectedPath;
                    string[] files = FileHelper.GetSubFiles(rootPath);
                    InvokeUploadFile(rootPath, files);
                }
            }
        }

        private void tsbtnClearUploadCmp_Click(object sender, EventArgs e)
        {
            TransTaskManager.Instance.UploadFileCollection.ClearCompleted();
        }


    }
}
